package zsj.androidknife.utilsImpl;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import zsj.androidknife.AndroidKnife;
import zsj.androidknife.Constants;
import zsj.androidknife.cache.CacheHelperImpl;
import zsj.androidknife.utils.BackgroundAction;
import zsj.androidknife.utils.IHttpUtils;
import zsj.androidknife.utils.UiAction;

/**
 * Created by Administrator on 2016/4/19 0019.
 */
public class HttpUtils implements IHttpUtils {

    private static class InstanceHolder {
        public static HttpUtils INSTANCE = new HttpUtils();
    }

    public static HttpUtils getInstance() {
        return InstanceHolder.INSTANCE;
    }

    private HttpUtils() {
    }

    @Override
    public void sendStringRequest(String url, final UiAction<String> uiAction) {
        AndroidKnife.getThreadUtils().startBackgroundTask(new BackgroundAction<String, String>() {
            @Override
            public String doInBackground(String param) {
                String value = getStringFromUrl(param);
                return value;
            }
        }, uiAction, url);
    }

    @Override
    public void sendJsonArrayRequest(String url, UiAction<JSONArray> uiAction) {
        AndroidKnife.getThreadUtils().startBackgroundTask(new BackgroundAction<String, JSONArray>() {
            @Override
            public JSONArray doInBackground(String param) {
                String value = getStringFromUrl(param);
                JSONArray array = null;
                try {
                    array = new JSONArray(value);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                return array;
            }
        }, uiAction, url);
    }

    @Override
    public void sendJsonObjectRequest(String url, UiAction<JSONObject> uiAction) {
        AndroidKnife.getThreadUtils().startBackgroundTask(new BackgroundAction<String, JSONObject>() {
            @Override
            public JSONObject doInBackground(String param) {
                String value = getStringFromUrl(param);
                JSONObject jsonObject = null;
                try {
                    jsonObject = new JSONObject(value);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                return jsonObject;
            }
        }, uiAction, url);

    }

    @Override
    public void sendBitmapRequest(String url, UiAction<Bitmap> uiAction) {
        AndroidKnife.getThreadUtils().startBackgroundTask(new BackgroundAction<String, Bitmap>() {
            @Override
            public Bitmap doInBackground(String param) {
                //先从缓存中取,如果没有再从网络取
                Bitmap bitmap = CacheHelperImpl.getInstance().getBitmap(param);
                if (bitmap != null) return bitmap;
                List list = getResponseISFromUrl(param);
                if (list == null) return null;
                int response = (int) list.get(0);
                InputStream is = (InputStream) list.get(1);
                bitmap = BitmapFactory.decodeStream(is);
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //将结果存到缓存
                CacheHelperImpl.getInstance().addBitmapToCache(bitmap, param);
                return bitmap;
            }
        }, uiAction, url);
    }

    /**
     * 返回的List第0元素是int值response,
     * 第1号元素是得到的InputStream
     * 如果获取失败返回null
     *
     * @param myurl
     * @return
     */
    private List getResponseISFromUrl(String myurl) {
        Context context = Constants.getContext();
        if (context != null) {
            //查看网络是否连通
            ConnectivityManager connMgr = (ConnectivityManager)
                    context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
            if (networkInfo == null || !networkInfo.isConnected()) {
                return null;
            }
        }
        //获取InputStream
        InputStream is = null;
        int response = -1;
        try {
            URL url = new URL(myurl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000 /* milliseconds */);
            conn.setConnectTimeout(15000 /* milliseconds */);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            // Starts the query
            conn.connect();
            response = conn.getResponseCode();
            is = conn.getInputStream();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (is == null) return null;
        List list = new ArrayList(2);
        list.add(response);
        list.add(is);
        return list;
    }

    private String getStringFromUrl(String myurl) {
        //先从缓存中取,如果没有再从网络取
        String value = CacheHelperImpl.getInstance().getString(myurl);
        if (value != null) return value;

        List list = getResponseISFromUrl(myurl);
        if (list == null) return null;
        int response = (int) list.get(0);
        InputStream is = (InputStream) list.get(1);
        Scanner s = new Scanner(is).useDelimiter("\\A");
        value = s.hasNext() ? s.next() : "";
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //将结果存到缓存
        CacheHelperImpl.getInstance().addStringToCache(myurl, value);
        return value;
    }
}
